package com.orientation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orientation.commom.exception.CustomException;
import com.orientation.dto.MajorInfoDto;
import com.orientation.entity.Class;
import com.orientation.entity.*;
import com.orientation.mapper.*;
import com.orientation.service.CollegeService;
import com.orientation.service.GoodsService;
import com.orientation.service.MajorService;
import com.orientation.utils.PageUtils;
import com.orientation.vo.MajorClassStudentVo;
import com.orientation.vo.MajorVo;
import com.orientation.vo.ProgressLengthVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.Collator;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 专业 服务实现类
 * </p>
 *
 * @author xuandian
 * @since 2022-3-9
 */
@Service
public class MajorServiceImpl extends ServiceImpl<MajorMapper, Major> implements MajorService {
    @Resource
    private MajorMapper majorMapper;
    @Resource
    private CollegeService collegeService;
    @Resource
    private CollegeMapper collegeMapper;
    @Resource
    private ClassMapper classMapper;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private ReserveMapper reserveMapper;
    @Resource
    private BedMapper bedMapper;
    @Resource
    private ReceiveMapper receiveMapper;
    @Resource
    private GoodsService goodsService;

    @Override
    public List<Major> findByCollegeId(String id) {
        return this.list(Wrappers.<Major>lambdaQuery().eq(Major::getCollegeId, id));
    }

    @Override
    public List<Major> queryMaj(String collegeId, Integer type) {
        LambdaQueryWrapper<Major> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Major::getDeleted, 0);
        if (StringUtils.hasLength(collegeId)) {
            queryWrapper.eq(Major::getCollegeId, collegeId);
        }
        if (StringUtils.hasLength(type.toString())) {
            queryWrapper.eq(Major::getState, type);
        }

        List<Major> pileList = majorMapper.selectList(queryWrapper);
        // 筛选不阶段名不为空情况
        List<Major> majorList = pileList.stream().filter((Major major) -> StringUtils.hasLength(major.getMajorName())).collect(Collectors.toList());
        //单个个LIst对象根据阶段名字段去重
        List<Major> distinct = majorList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(c -> c.getMajorName()))), ArrayList::new));
        //按照id排序
        //  List<PileStage> sorted = distinct.stream().sorted(Comparator.comparing(PileStage::getId)).collect(Collectors.toList());
        //z中文排序
        if (!CollectionUtils.isEmpty(distinct)) {
            comparatorMajorName(distinct);
        }
        return distinct;
    }

    @Override
    @Transactional
    public void insertMajor(MajorInfoDto majorInfoDto) {
        Major major = new Major();
        if (majorInfoDto != null && StringUtils.hasLength(majorInfoDto.getCollegeName())) {
            College college = collegeMapper.selectOne(new LambdaQueryWrapper<College>()
                    //     .eq(College::getDeleted, 0)
                    .eq(College::getCollegeName, majorInfoDto.getCollegeName())
            );
            Major major1 = majorMapper.selectOne(new LambdaQueryWrapper<Major>()
                    // .eq(Major::getDeleted, 0)
                    .eq(Major::getMajorName, majorInfoDto.getMajorName())
            );
            if (major1 != null) {
                throw new CustomException("18", "此专业已经存在,请不要重复添加");
            }
            if (college == null) {
                throw new CustomException("18", "院系输入错误或请先维护学院在进行专业维护");
            } else {
                majorInfoDto.setCollegeId(college.getSid());
                BeanUtils.copyProperties(majorInfoDto, major);
//                major.setEstabDate(majorInfoDto.getEstabDate());
            }
            save(major);
        }
    }

    @Override
    @Transactional
    public void saveMajor(Major major) {
        if (StringUtils.hasLength(major.getCollegeId()) ){
            College byId = collegeService.getById(major.getCollegeId());
            if (ObjectUtils.isEmpty(byId)) {
                throw new CustomException("18","学院信息选择错误");
            }
        }else {
            throw new CustomException("18","学院信息选择错误");
        }
        if (major.getMajorCode().length() != 1) {
            throw new CustomException("18", "专业编码填写错误请重新输入");
        }
        Major major1 = majorMapper.selectOne(new LambdaQueryWrapper<Major>()
                // .eq(Major::getDeleted, 0)
                 .eq(Major::getCollegeId, major.getCollegeId())
                .eq(Major::getMajorCode, major.getMajorCode())
        );

        if (major1 != null) {
            throw new CustomException("18", "此专业已经存在,请不要重复添加");
        } else {
            save(major);
        }

    }

    @Override
    public Page<MajorVo> queryMajor(Integer pageNum, Integer pageSize, String majorName, String collegeName, String estabDate) {
        College college = new College();
        if (StringUtils.hasLength(collegeName)) {
            college = collegeMapper.selectOne(new LambdaQueryWrapper<College>()
                    //  .eq(College::getDeleted, 0)
                    .eq(College::getCollegeName, collegeName)
            );
        }
        LambdaQueryWrapper<Major> queryWrapper = new LambdaQueryWrapper<>();
        //  queryWrapper.eq(Major::getDeleted, 0);
        if (StringUtils.hasLength(majorName)) {
            queryWrapper.eq(Major::getMajorName, majorName);
        }
        if (StringUtils.hasLength(college.getSid())) {
            queryWrapper.eq(Major::getCollegeId, college.getSid());
        }
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(estabDate)) {
            queryWrapper.ge(Major::getEstabDate, estabDate);
        }
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(estabDate)) {
            queryWrapper.le(Major::getEstabDate, estabDate);
        }
        List<Major> majorList = majorMapper.selectList(queryWrapper);
        Page<MajorVo> majorVoList = new Page<>();
        if (CollectionUtils.isEmpty(majorList)) {
            throw new CustomException("18", "当前暂无数据");
        } else {
            majorVoList = this.majorVoPage(majorList, pageNum, pageSize);
        }
/*
        List<Major> distinct = majorList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(c -> c.getCollegeId()))), ArrayList::new));
        comparatorMajorName(distinct);
        //得到
        List<String> collect = distinct.stream().map(Major::getCollegeId).collect(Collectors.toList());
        List<College> collegeList = collegeMapper.selectList(new LambdaQueryWrapper<College>()
                .eq(College::getDeleted, 0)
                .in(College::getSid, collect)
        );

        List<MajorVo> majorVos = new ArrayList<>();
        Page<MajorVo> majorVoPage = new Page<>();
        if (!CollectionUtils.isEmpty(collegeList)) {
            for (Major major : majorList) {
                for (College college : collegeList) {
                    if (college.getSid().equals(major.getCollegeId())) {
                        MajorVo majorVo = new MajorVo();
                        majorVo.setSid(major.getSid());
                        majorVo.setCollegeName(college.getCollegeName());
                        majorVo.setEstabDate(major.getEstabDate());
                        majorVo.setIntro(major.getIntro());
                        majorVo.setState(major.getState());
                        majorVo.setMajorName(major.getMajorName());
                        majorVo.setShortName(major.getShortName());
                        majorVo.setMajorCode(major.getMajorCode());
                        majorVos.add(majorVo);

                    }
                }
            }

            if (!CollectionUtils.isEmpty(majorVos)) {
                List<MajorVo> majorVoArrayList = majorVos.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(c -> c.getMajorName()))), ArrayList::new));//去重后的记录
                majorVoPage = PageUtils.getPage(majorVoArrayList, pageNum, pageSize);
            }

        }*/
        return majorVoList;

    }

    @Override
    public void updateStates(Major major) {
        if (major != null && StringUtils.hasLength(major.getSid()) && major.getState() != null) {
            updateById(major);
        } else {
            throw new CustomException("18", "sid未填写");
        }
    }

    /**
     * 匹配专业显示信息vo
     *
     * @param result
     * @param pageNum
     * @param pageSize
     * @return
     */
    private Page<MajorVo> majorVoPage(List<Major> result, Integer pageNum, Integer pageSize) {
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        Page<MajorVo> majorVoPage = new Page<>();
        //数据去重
        List<Major> distinct = result.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Major::getCollegeId))), ArrayList::new));
        //排序
        comparatorMajorName(distinct);
        //得到
        List<String> collect = distinct.stream().map(Major::getCollegeId).collect(Collectors.toList());
        List<College> collegeList = collegeMapper.selectList(new LambdaQueryWrapper<College>()
                //    .eq(College::getDeleted, 0)
                .in(College::getSid, collect)
        );
        List<Major> distinctMajor = result.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Major::getMajorName))), ArrayList::new));
        List<MajorVo> majorVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(collegeList)) {
            for (Major major : distinctMajor) {
                for (College college : collegeList) {
                    if (college.getSid().equals(major.getCollegeId())) {
                        MajorVo majorVo = new MajorVo();
                        majorVo.setSid(major.getSid());
                        majorVo.setCollegeName(college.getCollegeName());
                        majorVo.setEstabDate(major.getEstabDate());
                        majorVo.setIntro(major.getIntro());
                        majorVo.setAdviser(major.getAdviser());
                        majorVo.setAdviserId(major.getAdviserId());
                        majorVo.setState(major.getState());
                        majorVo.setMajorName(major.getMajorName());
                        majorVo.setShortName(major.getShortName());
                        majorVo.setMajorCode(major.getMajorCode());
                        majorVos.add(majorVo);

                    }
                }
            }

            if (!CollectionUtils.isEmpty(majorVos)) {
                List<MajorVo> majorVoArrayList = majorVos.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(c -> c.getMajorName()))), ArrayList::new));//去重后的记录
                majorVoPage = PageUtils.getPage(majorVoArrayList, pageNum, pageSize);
            }
        }
        return majorVoPage;
    }

    @Override
    public boolean updateState(String majorId, Integer state) {
        Major major = getById(majorId);
        if (major != null) {
            major.setState(state);
            updateById(major);
            return true;
        }
        return false;
    }

//    @Override
//    public void updateStates(Major major) {
//        if (major != null && StringUtils.hasLength(major.getSid())) {
//            major.setState(1);
//            updateById(major);
//        }
//    }

    @Override
    public Page<MajorVo> queryStateMajor(Integer pageNum, Integer pageSize, String majorName) {

        LambdaQueryWrapper<Major> queryWrapper = new LambdaQueryWrapper<>();
        //   queryWrapper.eq(Major::getDeleted, 0)
        queryWrapper.eq(Major::getState, 1);
        if (StringUtils.hasLength(majorName)) {
            queryWrapper.eq(Major::getMajorName, majorName);
        }
        Page<MajorVo> majorVoList = new Page<>();
        List<Major> majorList = majorMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(majorList)) {
            throw new CustomException("18", "当前暂无数据");
        } else {
            majorVoList = majorVoPage(majorList, pageNum, pageSize);
        }
        return majorVoList;
    }

    @Override
    public Major findByMajorCode(String code) {
        return this.getOne(Wrappers.<Major>lambdaQuery().eq(Major::getMajorCode, code));
    }

    @Override
    public List<MajorClassStudentVo> queryMajorName(String majorName) {
        List<MajorClassStudentVo> majorClassStudentVos = new ArrayList<>();
        Major major = majorMapper.selectOne(new LambdaQueryWrapper<Major>().eq(Major::getMajorName, majorName).eq(Major::getState, 1).groupBy(Major::getMajorName));
        if (major != null) {
            List<Class> classes = classMapper.selectList(new LambdaQueryWrapper<Class>().eq(Class::getMajorId, major.getSid()));
            if (!CollectionUtils.isEmpty(classes)) {
                //数据去重C
                List<Class> distinct = classes.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Class::getSid))), ArrayList::new));
                //取某个字段
                List<String> classesId = distinct.stream().map(Class::getSid).collect(Collectors.toList());
                List<Student> studentList = studentMapper.selectList(new LambdaQueryWrapper<Student>()
                        .in(Student::getClassId, classesId)
                );
                Map<String, List<Student>>integerListMap =new HashMap<>();
                if (!CollectionUtils.isEmpty(studentList)) {
                    List<Student> students = studentList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getIdCardNo))), ArrayList::new));
                   integerListMap = students.stream().collect(Collectors.groupingBy(Student::getClassId));
                }
                    for (Class ignored : classes) {
                        MajorClassStudentVo majorClassStudentVo = new MajorClassStudentVo();
                        majorClassStudentVo.setMajorName(major.getMajorName());
                        majorClassStudentVo.setClassName(ignored.getClassName());
                        if (!CollectionUtils.isEmpty(integerListMap.get(ignored.getSid()))) {
                            majorClassStudentVo.setChildrenStudent(integerListMap.get(ignored.getSid()));
                            majorClassStudentVo.setClassId(ignored.getSid());
                            majorClassStudentVo.setStudentNumber(integerListMap.get(ignored.getSid()).size());
                        }
                        majorClassStudentVos.add(majorClassStudentVo);
                    }

            }
        }
        return majorClassStudentVos;
    }

    @Override
    public Page<MajorClassStudentVo> queryPageMajorName(Integer pageNum, Integer pageSize, String majorName) {
        List<MajorClassStudentVo> majorClassStudentVos = queryMajorName(majorName);
        for (MajorClassStudentVo majorClassStudentVo:majorClassStudentVos){
            if (majorClassStudentVo.getStudentNumber()==null) {
                majorClassStudentVo.setStudentNumber(0);
            }
        }
        Page<MajorClassStudentVo> classStudentVoPage = new Page<>();
        if (CollectionUtils.isEmpty(majorClassStudentVos)) {
            throw new CustomException("18", "当前暂无数据");
        } else {
            classStudentVoPage = PageUtils.getPage(majorClassStudentVos, pageNum, pageSize);
        }
        return classStudentVoPage;
    }

    @Override
    public List<ProgressLengthVo> progressLengthVos(String collegeId) {
        List<ProgressLengthVo> lengthVos = new ArrayList<>();
        List<Student> students = studentMapper.selectList(new LambdaQueryWrapper<Student>().isNotNull(true, Student::getMajorId).isNotNull(true, Student::getStudentId).eq(StringUtils.hasLength(collegeId), Student::getCollegeId, collegeId));
        if (!CollectionUtils.isEmpty(students)) {


            List<Student> distinct = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getIdCardNo))), ArrayList::new));

            Map<String, List<Student>> integerListMap = distinct.stream().collect(Collectors.groupingBy(Student::getMajorId));
            List<String> majorIds = students.stream().map(Student::getMajorId).collect(Collectors.toList());
            //查询已经分配班级学号信息
            List<String> studentId = students.stream().map(Student::getStudentId).collect(Collectors.toList());
            //报道表存在学生信息
            //    List<Reserve> reserveList = reserveMapper.selectList(new LambdaQueryWrapper<Reserve>().isNotNull(true, Reserve::getStudentId));

            List<Major> majors = majorMapper.selectList(new LambdaQueryWrapper<Major>().in(Major::getSid, majorIds));
            for (Major major : majors) {
                ProgressLengthVo progressLengthVo = new ProgressLengthVo();
                if (StringUtils.hasLength(major.getSid()) && !CollectionUtils.isEmpty(integerListMap.get(major.getSid()))) {
                    List<String> studentsId = integerListMap.get(major.getSid()).stream().map(Student::getStudentId).collect(Collectors.toList());
                    List<Reserve> reserveList = reserveMapper.selectList(new LambdaQueryWrapper<Reserve>().in(Reserve::getStudentId, studentsId).eq(Reserve::getStatus, 3));
                    progressLengthVo.setMajorName(major.getMajorName());
                    progressLengthVo.setSumNum(integerListMap.get(major.getSid()).size());
                    BigDecimal installRate = new BigDecimal(reserveList.size()).multiply(new BigDecimal("100")).divide(new BigDecimal(integerListMap.get(major.getSid()).size()), 2, BigDecimal.ROUND_HALF_UP);

                    progressLengthVo.setFinishNum(installRate);
                    progressLengthVo.setNotNum(integerListMap.get(major.getSid()).size() - reserveList.size());
                    lengthVos.add(progressLengthVo);
                }
            }
        }
        return lengthVos;
    }

    @Override
    public List<ProgressLengthVo> getBedProgressLengthVos(String collegeId) {
        List<Student> students = studentMapper.selectList(new LambdaQueryWrapper<Student>().isNotNull(true, Student::getMajorId).isNotNull(true, Student::getStudentId).eq(StringUtils.hasLength(collegeId), Student::getCollegeId, collegeId));
        List<Student> distinct = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getIdCardNo))), ArrayList::new));

        Map<String, List<Student>> integerListMap = distinct.stream().collect(Collectors.groupingBy(Student::getMajorId));
        List<String> majorId = students.stream().map(Student::getMajorId).collect(Collectors.toList());
        //查询已经分配班级学号信息
        List<String> studentId = students.stream().map(Student::getStudentId).collect(Collectors.toList());
        //报道表存在学生信息
        //    List<Reserve> reserveList = reserveMapper.selectList(new LambdaQueryWrapper<Reserve>().isNotNull(true, Reserve::getStudentId));
        List<ProgressLengthVo> lengthVos = new ArrayList<>();
        List<Major> majors = majorMapper.selectList(new LambdaQueryWrapper<Major>().in(Major::getSid, majorId));
        for (Major major : majors) {
            ProgressLengthVo progressLengthVo = new ProgressLengthVo();
            if (StringUtils.hasLength(major.getSid()) && !CollectionUtils.isEmpty(integerListMap.get(major.getSid()))) {
                List<String> studentsId = integerListMap.get(major.getSid()).stream().map(Student::getStudentId).collect(Collectors.toList());
                List<Bed> reserveList = bedMapper.selectList(new LambdaQueryWrapper<Bed>().in(Bed::getStudentId, studentsId));
                progressLengthVo.setMajorName(major.getMajorName());
                progressLengthVo.setSumNum(integerListMap.get(major.getSid()).size());
                BigDecimal installRate = new BigDecimal(reserveList.size()).multiply(new BigDecimal("100")).divide(new BigDecimal(integerListMap.get(major.getSid()).size()), 2, BigDecimal.ROUND_HALF_UP);
                progressLengthVo.setFinishNum(installRate);
                progressLengthVo.setNotNum(integerListMap.get(major.getSid()).size() - reserveList.size());
                lengthVos.add(progressLengthVo);
            }
        }
        return lengthVos;
    }

    @Override
    public List<ProgressLengthVo> getGoodsProgressLengthVos(String collegeId) {
        List<Student> students = studentMapper.selectList(new LambdaQueryWrapper<Student>().isNotNull(true, Student::getMajorId).isNotNull(true, Student::getStudentId).eq(StringUtils.hasLength(collegeId), Student::getCollegeId, collegeId));
        List<Student> distinct = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getIdCardNo))), ArrayList::new));

        Map<String, List<Student>> integerListMap = distinct.stream().collect(Collectors.groupingBy(Student::getMajorId));
        List<String> majorId = students.stream().map(Student::getMajorId).collect(Collectors.toList());
        //查询已经分配班级学号信息
        List<String> studentId = students.stream().map(Student::getStudentId).collect(Collectors.toList());
        List<Goods> goodsList = goodsService.list();
        List<ProgressLengthVo> lengthVos = new ArrayList<>();
        List<Major> majors = majorMapper.selectList(new LambdaQueryWrapper<Major>().in(Major::getSid, majorId));
        for (Major major : majors) {
            ProgressLengthVo progressLengthVo = new ProgressLengthVo();
            if (StringUtils.hasLength(major.getSid()) && !CollectionUtils.isEmpty(integerListMap.get(major.getSid()))) {
                List<String> studentsId = integerListMap.get(major.getSid()).stream().map(Student::getStudentId).collect(Collectors.toList());
                List<Receive> reserveList = receiveMapper.selectList(new LambdaQueryWrapper<Receive>().in(Receive::getStudentId, studentsId));
                Map<String, List<Receive>> stringListMap = reserveList.stream().collect(Collectors.groupingBy(Receive::getStudentId));
                stringListMap.size();

                int count = 0;
                for(String s:studentsId){
                    if (!CollectionUtils.isEmpty(stringListMap.get(s)) && stringListMap.get(s).size() == goodsList.size()) {
                        count+=1;
                    }
                }

                progressLengthVo.setMajorName(major.getMajorName());
                progressLengthVo.setSumNum(integerListMap.get(major.getSid()).size());
                BigDecimal installRate = new BigDecimal(count).multiply(new BigDecimal("100")).divide(new BigDecimal(integerListMap.get(major.getSid()).size()), 2, BigDecimal.ROUND_HALF_UP);
                progressLengthVo.setFinishNum(installRate);
                progressLengthVo.setNotNum(integerListMap.get(major.getSid()).size() - count);
                lengthVos.add(progressLengthVo);
            }
        }
        return lengthVos;
    }

    /**
     * 按中文首字母桩号排序
     *
     * @param result
     * @return
     */
    private List<Major> comparatorMajorName(List<Major> result) {
        Comparator comparator = Collator.getInstance(Locale.CHINA);
        Collections.sort(result, (o1, o2) -> comparator.compare(o1.getMajorName(), o2.getMajorName()));
        return result;
    }

}


